/**
 *  每个command可能会依赖一些不同的对象.
 *  同一个对象可能在不同的command中,当某个command的操作中,
 *  对其所依赖的对象进行了 添加/删除时,可能会影响其他的 command.
 *
 *  所以需要记录 每个command 所依赖的对象, 再删除依赖对象的时候 进行检查.
 *
 *
 *  再进一步, 具体的逻辑为:
 *
 *    存在一个bug: 就是在 lstSel 中间进行添加和删除.
 *    case1:   execute 中添加新的对象A,  需要检查后续的 command 对象是否依赖了 A.
 *    case2:   execute 中删除了对象B, 需要检查之前的 command 对象是否依赖了B.
 *
 *    // 所以直接修改所有依赖
 *
 *    bug2:  cmd1->cmd2->cmd3->cmd4->cmd5
 *    比如 cmd3中新增了一个对象A,A 又不会在 cmd3的依赖中,
 *      当在 cmd5 中删除A时, cmd3 中的A 还在,导致bug.
 *
 *    解决方法:
 *       每个命令都有一个 depenObjs 对象,里面存了 name:obj 键值对.
 *       每当一个command里面 发生 添加/删除 某个对象A,
 *       就去所有的 command(支持subCommands) 里面去查找是否使用了 A,
 *       如果使用了就记录下来, 在 execute/undo 里面去更新 A 的引用......
 */
class Command {
    constructor() {
        this.id = -1;

        // 是否可更新
        this.updatable = false;

        this.name = '';
        this.type = '';

        // unused
        this.object = undefined;
        this.script = undefined;

        // 当前命令所依赖的对象
        this.depenObjs = {};
        this.subCmds = [];
    }

    setObj(name,obj){

        this.depenObjs[name] = obj;

        // let oldObj = this.depenObjs[name];
        //
        // if(oldObj){
        //     if(oldObj === obj){
        //         return;
        //     }else{
        //         // 先删除原来的
        //         this._removeDepenItemByName(name);
        //     }
        // }
        //
        // let item = new DepenItem(name,obj);
        // this.depens.push(item);
        // this.depenObjs[name] = item;
    }

    getObj(name){
        return this.depenObjs[name];
    }

    _getAllDepenItem(obj){

        myTools.asset(obj,'obj is not null!');

        let items = [];

        // 先获取自身的
        for(let k in this.depenObjs){
            if(this.depenObjs[k] === obj){
                items.push({name:k,obj:obj,cmd:this});
            }
        }


        // 再获取 subCmds 的
        if(this.subCmds.length > 0){
            this.subCmds.forEach(cmd=>{
                 items = items.concat(cmd._getAllDepenItem(obj));
            });
        }

        return items;
    }

    getDepenItems(obj) {
        let affects = [];
        let cmds = editor.history.getAllCmds();
        cmds.forEach(cmd => {
            let items = cmd._getAllDepenItem(obj);
            if (items.length > 0) {
                affects = affects.concat(items)
            }
        });
        return affects;
    }

    cleanAffectLst(lst) {
        lst.forEach(item => {
            item.cmd.setObj(item.name,null);
        });
    }

    setAffectLst(lst, obj) {
        lst.forEach(item => {
            item.cmd.setObj(item.name,obj);
        });
    }
}


module.exports = Command;
